home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 May: Tool Chest / Dev.CD May 97 TC.toast / Sample Code / Devices / ATA demo / ATA Demo.c next >
Encoding:
Text File  |  1997-01-14  |  18.9 KB  |  632 lines  |  [TEXT/CWIE]

  1. /*/*************************************************************************
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    Macintosh ATA Manager Sample 
  5. **
  6. **    by Vinne Moscaritolo, <vinnie@apple.com>
  7. **    Apple Developer Technical Support 
  8. **
  9. **  Created from as much sample code I could find.
  10. **  with much help from Gary Wilkinson, Rich Schnell and  Martin Minow
  11. **
  12. **  " Good Artists Imitate, Great Artist Steal "
  13. **
  14. **    File:        ATA Demo.c
  15. **
  16. **    Copyright © 1996 Apple Computer, Inc.
  17. **    All rights reserved.
  18. **
  19. **    You may incorporate this sample code into your applications without
  20. **    restriction, though the sample code has been provided "AS IS" and the
  21. **    responsibility for its operation is 100% yours.  However, what you are
  22. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  23. **    after having made changes. If you're going to re-distribute the source,
  24. **    we require that you make it clear in the source that the code was
  25. **    descended from Apple Sample Code, but that you've made changes.
  26. **
  27. **************************************************************************/
  28.  
  29.  
  30.  
  31. //------------------------------------------------------------------------------------
  32. #pragma mark Includes
  33. //------------------------------------------------------------------------------------
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <ATA.h>
  37.  
  38. //------------------------------------------------------------------------------------
  39. #pragma mark Defines
  40. //------------------------------------------------------------------------------------
  41.  
  42. //
  43. // Identifies the bus protocol type.
  44. //
  45.  
  46. enum {
  47.     kDevUnknown        =    0,
  48.     kDevATA            =    1,
  49.     kDevATAPI        =    2,
  50.     kDevPCMCIA        =    3
  51. };
  52.  
  53. //
  54. // Identifies the Socket type.
  55. //
  56. enum {
  57.     kSocketUnknown        =    0,
  58.     kSocketInternal        =    1,
  59.     kSocketMediaBay        =    2,
  60.     kkSocketPCMCIA        =    3
  61. };
  62.  
  63. //------------------------------------------------------------------------------------
  64. #pragma mark Macros
  65. //------------------------------------------------------------------------------------
  66.  
  67. #define CLEAR(what) do {                        \
  68.         register Ptr        _ptr = (Ptr) &what;    \
  69.         register Size        _len = sizeof what;    \
  70.         for (; _len > 0; --_len)                    \
  71.             *_ptr++ = 0;                        \
  72.     } while (0)
  73.  
  74. #define IF_ERROR(_err_,_str_) if (_err_ != noErr) { printf(_str_); return (_err_); }
  75.  
  76.  
  77. //------------------------------------------------------------------------------------
  78. #pragma mark -
  79.  
  80. //------------------------------------------------------------------------------------
  81. #pragma mark Identify Drive Info
  82. //------------------------------------------------------------------------------------
  83.  
  84. //
  85. //  Bit fields returned from Identify Drive command
  86. //
  87. enum {
  88.     magdrv_bit        =    15,            /* WORD 0: bit number of mag drive indicator    */
  89.     rcd_bit            =    7,            /* WORD 0: bit number of removable indicator    */
  90.     fixed_bit        =    6,            /* WORD 0: bit number of fixed disk indicator    */
  91.  
  92.     lbamode_bit        =    9,            /* bit number of lba support indicator            */
  93.     iordy_bit        =    11,            /* bit number of IORDY support indicator        */
  94.     extvalid_bit    =    1,            /* bit number of valid extension word            */
  95.     mode3_bit        =    0,            /* WORD 64: bit number of mode 3 support        */
  96.     
  97.     kMagDrv            =    1 << magdrv_bit,    /* Bit 15 = 0 -> a magnetic drive        */
  98.     kRemovable        =    1 << rcd_bit,        /* Bit 7 != 0 -> removable cartridge    */
  99.     kFixed            =    1 << fixed_bit,        /* Bit 6 != 0 -> indicates fixed drive    */
  100.     kLBAMode        =    1 << lbamode_bit,    /* LBA support indicator                */
  101.     kIORDY            =    1 << iordy_bit,        /* IORDY support indicator                */
  102.     kExtValid        =    1 << extvalid_bit,    /* Extension word valid                    */
  103.     MODE3BIT        =    1 << mode3_bit        /* mode 3 bit in word 64 of ident data    */
  104. };
  105.  
  106. //
  107. // This is returned by the device in response to an IDENTIFY command (512 bytes).
  108. //
  109. typedef    struct IdentifyBlock {    /* Structure of Identify data                        */
  110.     short    Signature;            /* Word 00: Constant value                            */
  111.     short    NumCyls;            /* Word 01:    Number of cylinders (default mode)            */
  112.     short    RSVD0;                /* Word 02:    Constant value of 0                        */
  113.     short    NumHds;                /* Word 03:    Number of heads (default mode)            */
  114.     short    TrkBytes;            /* Word 04:    Number of unformatted bytes/track        */
  115.     short    SecBytes;            /* Word 05:    Number of unformatted bytes/sector        */
  116.     short    NumSecs;            /* Word 06:    Number of sectors/track                    */
  117.     short    VU0;                /* Word 07:    Vendor unique                            */
  118.     short    VU1;                /* Word 08:    Vendor unique                            */
  119.     short    VU2;                /* Word 09:    Vendor unique                            */
  120.     short    Serial[10];            /* Word 10-19:    Serial Number (right-justified)        */
  121.     short    BufType;            /* Word 20:    Buffer Type                                */
  122.     short    BufSize;            /* Word 21:    Buffer size in 512 byte increments        */
  123.     short    NumECC;                /* Word 22:    Number of ECC bytes                        */
  124.     short    FirmRev[4];            /* Word 23-26:    Firmware revision (left-justified)    */
  125.     short    ModelNum[20];        /* Word 27-46:    Model number (left-justified)        */
  126.     short    MultCmds;            /* Word 47:    R/W multiple commands not impl = 0        */
  127.     short    DblXferFlag;        /* Word 48:    Double transfer flag                    */
  128.     short    Capabilities;        /* Word 49: LBA, DMA, IORDY support indicator        */
  129.     short    Reserved1;            /* Word 50: Reserved                                */
  130.     short    PIOTiming;            /* Word 51: PIO transfer timing mode                */
  131.     short    DMATiming;            /* Word 52:    DMA transfer timing mode                */
  132.     short    Extension;            /* Word 53: extended info support                    */
  133.     short    CurCylinders;        /* Word 54: number of current cylinders                */
  134.     short    CurHeads;            /* Word 55: number of current heads                    */
  135.     short    CurSPT;                /* Word 56: number of current sectors per track        */
  136.     short    CurCapacity[2];        /* Word 57-58: current capacity in sectors            */
  137.     short    MultSectors;        /* Word 59: Multiple sector setting                    */
  138.     short    LBACapacity[2];        /* Word 60-61: total sectors in LBA mode            */
  139.     short    SWDMA;                /* Word 62: single word DMA support                    */
  140.     short    MWDMA;                /* Word 63: multi word DMA support                    */
  141.     short    APIOModes;            /* Word 64:    Advanced PIO Xfr mode supported            */
  142.     short    MDMATiming;            /* Word 65:    Minimum Multiword DMA Xfr Cycle            */
  143.     short    RDMATiming;            /* Word 66:    Recommended Multiword DMA Cycle            */
  144.     short    MPIOTiming;            /* Word 67:    Min PIO XFR Time W/O Flow Control        */
  145.     short    PIOwRDYTiming;        /* Word 68:    Min PIO XFR Time with IORDY flow ctrl    */
  146.     short    Reserved[187];        /* Word 69-255: Reserved                            */
  147. } IdentifyBlock;
  148.  
  149. //
  150. // The following structure and table simplifies the formatting.
  151. //
  152. enum {
  153.     kEndOfTable = 0,            /* Marker                                            */
  154.     kDecimal,                    /* Signed integer (two words are high..low)            */
  155.     kHex,                        /* Bitfield                                            */
  156.     kLeftJust,                    /* Ascii, left-justified, space padded                */
  157.     kRightJust                    /* Ascii, right-justified, space padded                */
  158. };
  159. struct FormatTable {
  160.     short        firstWord;        /* First word in IdentifyBlock cast to short vector    */
  161.     short        lastWord;        /* Last word in IdentifyBlock cast to short vector    */
  162.     short        format;            /* Format from above enum                            */
  163.     const char    *label;            /* Text to display                                    */
  164. };
  165.  
  166. typedef struct FormatTable FormatTable, *FormatTablePtr;
  167.  
  168. FormatTable kIdentFormat[] = {
  169.     {     0,     0, kHex,        "Configuration word"                        },
  170.     {     1,     1,    kDecimal,    "Cylinders"            },
  171.     {     3,     3,    kDecimal,    "Heads"                },
  172.     {     4,     4,    kDecimal,    "Bytes/Track"            },
  173.     {     5,     5,    kDecimal,    "Bytes/Sector"        },
  174.     {     5,     5,    kDecimal,    "Sectors/Track"        },    /* 35 */
  175.     {     7,     9,    kHex,        "Vendor Unique (word 7..9)"                    },
  176.     {    10,    19,    kRightJust,    "Serial Number"                                },
  177.     {    20,    20,    kHex,        "Buffer Type"                                },
  178.     {    21,    21,    kDecimal,    "Buffer size in 512 byte increments"        },
  179.     {    22,    22,    kDecimal,    "Number of ECC bytes available"                },
  180.     {    23,    26,    kLeftJust,    "Firmware Revision"                            },
  181.     {    27,    46,    kLeftJust,    "Model Number"                                },
  182.     {    47,    53,    kHex,        "Capability Flags (word 47..53)"            },
  183.     {    54,    54,    kDecimal,    "Cylinders (current mode)"        },
  184.     {    55,    55,    kDecimal,    "Heads (current mode)"            },
  185.     {    56,    56,    kDecimal,    "Sectors/Track (current mode)"        },
  186.     {    57,    58,    kDecimal,    "Current Capacity in Sectors"                },
  187.     {    59,    59,    kHex,        "Multiple Sector Capability Flag"            },
  188.     {    60,    61,    kDecimal,    "Current User-addressable Sectors"            },
  189.     {    62,    62,    kHex,        "Single Word DMA Transfer Mode Flags"        },
  190.     {    63,    63,    kHex,        "Multiword DMT Transfer Mode Flags"            },
  191.     {     0,  0,    kEndOfTable,""                                            }
  192. };
  193.  
  194.  
  195.  
  196. //------------------------------------------------------------------------------------
  197. #pragma mark Prototypes
  198. //------------------------------------------------------------------------------------
  199.  
  200. Boolean     ATAManagerPresent    (void);
  201. Boolean     ATAHardwarePresent    (void);
  202. Boolean     TrapAvailable        (short theTrap);
  203. void         PrintNumVersion        (char *label, NumVersion version );
  204. OSErr         DisplayATAManagerInquiryInfo (void);
  205.  
  206. OSErr         ScanATABusses         (void);
  207. OSErr         DisplayATADriveIdentity (UInt32 deviceID );
  208. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length );
  209. void        DumpFormatedBuffer    (void* p, const  FormatTablePtr formatPtr);
  210. char*        DrvrRefToName        (short refNum);
  211.  
  212.  
  213.  
  214. //------------------------------------------------------------------------------------
  215. #pragma mark -
  216.  
  217.  
  218. // ---------------------------------------------------------------------------
  219. void     main     (void)
  220. // ---------------------------------------------------------------------------
  221. {
  222.     OSErr            status;
  223.     
  224.     printf("Macintosh ATA Manager Sample\n\n");
  225.  
  226. // Check for ATA Hardware 
  227. // you should do this before calling the ATAManager, since some early ROMS
  228. // could indicate an ATA manager without the proper HW, thus casing a crash.
  229.     if (ATAHardwarePresent() == FALSE) {
  230.         printf("ATA Hardware is not present on this system\n");
  231.         exit(EXIT_FAILURE);
  232.     }
  233.  
  234. // Check for ATA Manager
  235.     if (ATAManagerPresent() == FALSE) {
  236.         printf("ATA Manager is not present on this system\n");
  237.         exit(EXIT_FAILURE);
  238.     }
  239.         
  240. // Display ATA Manager Info
  241.     status = DisplayATAManagerInquiryInfo();
  242.     if (status != noErr) {
  243.         printf("Cannot access ATA Manager: %d\n", (int) status);
  244.         exit(EXIT_FAILURE);
  245.     }
  246.     
  247. // Display ATA Device Info
  248.     status = ScanATABusses();
  249.     if (status != noErr) {
  250.         printf("Cannot access ATA Manager: %d\n", (int) status);
  251.         exit(EXIT_FAILURE);
  252.     }
  253. }
  254.  
  255.  
  256. // ---------------------------------------------------------------------------
  257. OSErr         DisplayATAManagerInquiryInfo (void)
  258. // ---------------------------------------------------------------------------
  259. //
  260. //  Display information about the ATA Manager
  261. //
  262. {
  263.     ataMgrInquiry    pb;
  264.     OSErr            status;
  265.  
  266.     CLEAR(pb);
  267.     
  268.     pb.ataPBFunctionCode =    kATAMgrManagerInquiry;
  269.     pb.ataPBVers =            kATAPBVers1;
  270.  
  271.     status = ataManager((ataPB*) &pb );
  272.     IF_ERROR(status, "ATA Manager Inquiry failed\n")
  273.  
  274.     printf("ATA Manager inquiry:\n");
  275.     PrintNumVersion("\tATA Manager Version:", pb.ataMgrVersion);
  276.     printf("\tBusses:\t\t%d\n\tDevices:\t%d\n",
  277.                 pb.ataBusCnt, pb.ataDevCnt);
  278.     printf("\tPIO Modes:\t%x\n\tDMA Modes:\t%d\n\tMulti DMA Modes:%x\n",
  279.                  pb.ataPioModes, pb.ataSingleDMAModes, pb.ataMultiDMAModes);
  280.     printf("-----------------------------------------\n\n");    
  281.     return (status);
  282. }
  283.  
  284.  
  285. // ---------------------------------------------------------------------------
  286. OSErr         ScanATABusses (void)
  287. // ---------------------------------------------------------------------------
  288. //
  289. //  Display information about the ATA Busses
  290. //
  291. {
  292.     ataDrvrRegister        pb;
  293.     OSErr                status;
  294.  
  295. // Get first device ID (yes you have to do this once)
  296.     CLEAR(pb);
  297.     pb.ataPBFunctionCode     =    kATAMgrFindDriverRefnum;
  298.     pb.ataPBVers            =    kATAPBVers1;
  299.     pb.ataPBDeviceID         =     (UInt32)0x0000ffff;
  300.     status                     =     ataManager((ataPB*) &pb );
  301.  
  302. // loop through devices
  303.     for    (pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID;
  304.          pb.ataPBDeviceID != 0xff;
  305.          pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID)
  306.         {             
  307.             status = ataManager((ataPB*) &pb );
  308.             IF_ERROR(status, "ATA Find Driver failed\n")
  309.             
  310.             printf("Device %d %#s\n", pb.ataPBDeviceID, DrvrRefToName(pb.ataDrvrRefNum) );
  311.             DisplayATADriveIdentity(pb.ataPBDeviceID);
  312.             
  313.         printf("-----------------------------------------\n\n");    
  314.         };    
  315.     
  316.     printf("\n");    
  317.     return (status);
  318. }
  319.  
  320.  
  321.  
  322. // ---------------------------------------------------------------------------
  323. OSErr         DisplayATADriveIdentity (UInt32 deviceID)
  324. // ---------------------------------------------------------------------------
  325. //
  326. //  Display information about the ATA Identify Info
  327. //
  328. {
  329.     ataIdentify            pb;
  330.     ataDevConfiguration    pb1;
  331.     
  332.     UInt16        buffer[255];
  333.     OSErr        status;
  334.     
  335.  
  336. // Get Driver Configuration
  337.     CLEAR(pb1);
  338.     pb1.ataPBFunctionCode     =    kATAMgrGetDrvConfiguration;
  339.     pb1.ataPBVers            =    kATAPBVers2;
  340.     pb1.ataPBDeviceID         =    deviceID;
  341.     
  342.     status = ataManager((ataPB*) &pb1 );
  343.     IF_ERROR(status, "ATA GetDrvConfiguration failed\n")
  344.  
  345.  
  346. // Setup Identify block;
  347.     CLEAR(pb);
  348.     pb.ataPBFunctionCode     =    kATAMgrDriveIdentify;
  349.     pb.ataPBVers            =    kATAPBVers1;
  350.     pb.ataPBDeviceID        =    deviceID;
  351.      pb.ataPBFlags             =     mATAFlagIORead + mATAFlagByteSwap ;
  352.      
  353.      if(pb1.ataDeviceType == kDevATAPI) pb.ataPBFlags += mATAFlagProtocol1;
  354.      
  355.     pb.ataPBTimeOut            =    100;
  356.     pb.ataPBBuffer            =    (void*) buffer;
  357.     
  358.     status = ataManager((ataPB*) &pb );
  359.     IF_ERROR(status, "ATA DriveIdentify failed\n")
  360.  
  361.     printf("Configuration: (");
  362.  
  363.     switch(pb1.ataDeviceType){
  364.         case kDevUnknown:    
  365.                         printf("Unknown protocol"); 
  366.                         break;
  367.         
  368.         case kDevATA:
  369.                         printf("ATA"); 
  370.                         break;
  371.                              
  372.         case kDevATAPI:    
  373.                         printf("ATAPI"); 
  374.                         break;
  375.                         
  376.         case kDevPCMCIA:    
  377.                         printf("PCMCIA"); 
  378.                         break;
  379.     }
  380.     
  381.     switch(pb1.ataSocketType){
  382.         case kSocketUnknown:    
  383.                         printf(", Unknown Socket"); 
  384.                         break;
  385.         
  386.         case kSocketInternal:
  387.                         printf(", Internal"); 
  388.                         break;
  389.                              
  390.         case kSocketMediaBay:    
  391.                         printf(", Media Bay"); 
  392.                         break;
  393.                         
  394.         case kkSocketPCMCIA:    
  395.                         printf(", PCMCIA, Vcc=%d, Vpp1=%d, Vpp2=%d", 
  396.                                         pb1.atapcVcc, pb1.atapcVpp1,pb1.atapcVpp2); 
  397.                         break;
  398.     }
  399.  
  400.     printf(")\n");
  401.  
  402.     DumpFormatedBuffer(buffer, kIdentFormat);
  403. };
  404.  
  405.  
  406.  
  407.  
  408. // ---------------------------------------------------------------------------
  409. Boolean     ATAManagerPresent    (void)
  410. // ---------------------------------------------------------------------------
  411. //
  412. // returns true if this machine has the ata manager
  413. //
  414. {
  415.         return (TrapAvailable(kATATrap));
  416. }
  417.  
  418. // ---------------------------------------------------------------------------
  419. Boolean     ATAHardwarePresent        (void)
  420. // ---------------------------------------------------------------------------
  421. //
  422. // returns true if this machine has ata hardware
  423. //
  424. {
  425.     UInt16    configFlags;
  426.  
  427.     // Hardware configuration flags
  428.     configFlags = LMGetHWCfgFlags();
  429.     
  430.     return (configFlags & 0x0080);
  431. }
  432.  
  433. //------------------------------------------------------------------------------------
  434. #pragma mark -
  435.  
  436. #define NumToolboxTraps() (                                \
  437.         (NGetTrapAddress(_InitGraf, ToolTrap)            \
  438.                 == NGetTrapAddress(0xAA6E, ToolTrap))    \
  439.             ? 0x200 : 0x400                                \
  440.     )
  441. #define GetTrapType(theTrap) (                            \
  442.         (((theTrap) & 0x800) != 0) ? ToolTrap : OSTrap    \
  443.     )
  444.  
  445. // ---------------------------------------------------------------------------
  446. Boolean     TrapAvailable        (short theTrap)
  447. // ---------------------------------------------------------------------------
  448. // (see Inside Mac VI 3-8)
  449. {
  450.         TrapType                trapType;
  451.         
  452.         trapType = GetTrapType(theTrap);
  453.         if (trapType == ToolTrap) {
  454.             theTrap &= 0x07FF;
  455.             if (theTrap >= NumToolboxTraps())
  456.                 theTrap = _Unimplemented;
  457.         }
  458.         return (
  459.             NGetTrapAddress(theTrap, trapType)
  460.             != NGetTrapAddress(_Unimplemented, ToolTrap)
  461.         );
  462. }
  463.  
  464. // ---------------------------------------------------------------------------
  465. void         PrintNumVersion        (char *label, NumVersion version )
  466. // ---------------------------------------------------------------------------
  467. //
  468. //    Decode version number info
  469. //
  470. {
  471.     char            *stage;
  472.  
  473.     switch (version.stage) {
  474.     case developStage:    stage = "d";        break;
  475.     case alphaStage:    stage = "a";        break;
  476.     case betaStage:        stage = "b";        break;
  477.     case finalStage:    stage = "";            break;
  478.     default:            stage = "?";        break;
  479.     
  480.     }
  481.     printf("%s %d.%d.%d",
  482.         label,
  483.         version.majorRev,
  484.         (version.minorAndBugRev>>4), (version.minorAndBugRev & 0xf),
  485.         stage);
  486.     if(version.stage != finalStage) printf(".%d",version.nonRelRev);
  487.     
  488.     printf(" (hex %08lx)\n",    (* ((unsigned long *) &version)));
  489. }
  490.  
  491.  
  492.  
  493. // ---------------------------------------------------------------------------
  494. void        DumpFormatedBuffer    (void* p,  const FormatTablePtr format) 
  495. // ---------------------------------------------------------------------------
  496. //
  497. // Dump formatted buffer
  498. //
  499.  
  500. {    
  501.     unsigned short            *idInfo = p;
  502.          
  503.     register char            *charField;
  504.     register short            fieldLength;
  505.     register short            i;
  506.     register long            value;
  507.     register FormatTablePtr    formatPtr;
  508.     
  509. #define FORMAT    (*formatPtr)
  510.  
  511.     for (formatPtr = format; FORMAT.format != kEndOfTable; formatPtr++) {
  512.             printf("%35s", FORMAT.label);
  513.             switch (FORMAT.format) {
  514.             case kDecimal:
  515.                 value = 0;
  516.                 for (i = FORMAT.firstWord; i <= FORMAT.lastWord; i++) {
  517.                     value <<= 16;
  518.                     value += idInfo[i];
  519.                 }
  520.                 printf(" %lu", value);
  521.                 break;
  522.             case kHex:
  523.                 for (i = FORMAT.firstWord; i <= FORMAT.lastWord; i++) {
  524.                     value = idInfo[i];
  525.                     printf(" %04lx", value);
  526.                 }
  527.                 break;
  528.             case kLeftJust:
  529.                 charField = (char *) &idInfo[FORMAT.firstWord];
  530.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  531.                             * sizeof (unsigned short);
  532.                 /*
  533.                  * First scan for an unspecified field.
  534.                  */
  535.                 for (i = 0; i <= fieldLength; i++) {
  536.                     if (charField[i] != '\0')
  537.                         goto gotLeftJustField;
  538.                 }
  539.                 printf(" <not specified>");
  540.                 break;
  541. gotLeftJustField:
  542.                 for (i = fieldLength; i > 0; --i) {
  543.                     if (charField[i - 1] != ' ')
  544.                         break;
  545.                 }
  546.                 printf(" \"%.*s\"", (int) i, charField);
  547.                 break;
  548.             case kRightJust:
  549.                 charField = (char *) &idInfo[FORMAT.firstWord];
  550.                 fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
  551.                             * sizeof (unsigned short);
  552.                 /*
  553.                  * First scan for an unspecified field.
  554.                  */
  555.                 for (i = 0; i <= fieldLength; i++) {
  556.                     if (charField[i] != '\0')
  557.                         goto gotRightJustField;
  558.                 }
  559.                 printf(" <not specified>");
  560.                 break;
  561. gotRightJustField:
  562.                 for (i = 0; i < fieldLength; i++) {
  563.                     if (charField[i] != ' ')
  564.                         break;
  565.                 }
  566.                 printf(" \"%.*s\"", (int) (fieldLength - i), &charField[i]);
  567.                 break;
  568.             }
  569.             printf("\n");
  570.         }
  571. //        DumpRawBuffer( p,512);
  572. }    
  573.     
  574. // ---------------------------------------------------------------------------
  575. void        DumpRawBuffer        ( UInt8 *bufferPtr, int length )
  576. // ---------------------------------------------------------------------------
  577. //
  578. // Dump buffer
  579. //
  580.  
  581. {
  582.         register int            i;
  583.         int                        lineStart;
  584.         int                        lineLength;
  585.         short                    c;
  586.  
  587. #define kLineSize    16
  588.         for (lineStart = 0; lineStart < length; lineStart += lineLength) {
  589.             lineLength = kLineSize;
  590.             if (lineStart + lineLength > length)
  591.                 lineLength = length - lineStart;
  592.             printf("%03x %3d:", lineStart, lineStart);
  593.             for (i = 0; i < lineLength; i++)
  594.                 printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
  595.             for (; i < kLineSize; i++)
  596.                 printf("   ");
  597.             printf("  ");
  598.             for (i = 0; i < lineLength; i++) {
  599.                 c = bufferPtr[lineStart + i] & 0xFF;
  600.                 if (c > ' ' && c < '~')
  601.                     printf("%c", c);
  602.                 else {
  603.                     printf(".");
  604.                 }
  605.             }
  606.             printf("\n");
  607.         }
  608. }
  609.  
  610.  
  611.         
  612. // ---------------------------------------------------------------------------
  613. char*        DrvrRefToName(short refNum)
  614. // ---------------------------------------------------------------------------
  615. //
  616. //  lookup driver name in table
  617. //
  618.  
  619. {
  620.         AuxDCEHandle*        UTable  = (AuxDCEHandle*) LMGetUTableBase();
  621.         DCtlPtr                dctl;
  622.         Ptr                    p;    
  623.         
  624.         if(!refNum) return ((char*) "\p<none>");
  625.  
  626.         dctl = (DCtlPtr) *UTable[~refNum];
  627.         p      =  dctl->dCtlDriver;
  628.         if( dctl->dCtlFlags  & 0x0040) p = (void*) *p;
  629.  
  630.         return  ( p?(char*) (p+18):(char*)"\p-Purged-");
  631. }
  632.